package com.example.intelligentattendancesystem.service.impl;

import com.alibaba.fastjson.serializer.DateCodec;
import com.example.intelligentattendancesystem.Utils.Utile;
import com.example.intelligentattendancesystem.mapping.LeaveMapping;
import com.example.intelligentattendancesystem.mapping.UserMapping;
import com.example.intelligentattendancesystem.mapping.WorkMapping;
import com.example.intelligentattendancesystem.pojo.Leave;
import com.example.intelligentattendancesystem.pojo.User;
import com.example.intelligentattendancesystem.pojo.Work;
import com.example.intelligentattendancesystem.service.WorkService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author
 * @version 1.0
 * @className WorkServiceImpl
 * @since 1.0
 */
@Service
public class WorkServiceImpl implements WorkService {
    @Autowired
    WorkMapping workMapping;
    @Autowired
    Utile utile;
    @Autowired
    UserMapping userMapping;
    @Autowired
    LeaveMapping leaveMapping;
    @Transactional
    @Override
    public Boolean setTimeTableService(List<Work> works) {

//        如果开始时间一样就不添加
        List<Work> works1 = workMapping.selectWorkByUserId(works.get(0).getUserId());
        //查询所有员工，将员工也添加进数据库
        List<User> users = userMapping.selectAllUser();
//        System.out.println(works1);
        for(int k=0;k<works1.size();k++){
            for(int l=0;l<works.size();l++){
//                若新的表的开始时间或者结束时间在之前的时刻表格中，就无法设置
                if(((works1.get(k).getStartTime().compareTo(works.get(l).getStartTime())<=0 && works1.get(k).getEndTime().compareTo(works.get(l).getStartTime())>=0)
                  || (works1.get(k).getStartTime().compareTo(works.get(l).getEndTime())<=0 && works1.get(k).getEndTime().compareTo(works.get(l).getEndTime())>=0))
                  ||  works1.get(k).getStartTime().compareTo(works.get(l).getStartTime())>=0 && works1.get(k).getEndTime().compareTo(works.get(l).getEndTime())<=0){
                    works.remove(works.get(l));
                    l--;
                }
            }

        }



        int count=0,i=0,j=0;
        for (i = 0; i < works.size(); i++) {
            //添加了一个week为-1的时间
            count+=workMapping.insertWork(works.get(i));
            //需要时间为1,2,3,4,5，的week，每个用户都需要
            for (j = 0; j < users.size(); j++) {
                works.get(i).setWeek("1");
                works.get(i).setUserId(users.get(j).getUserId());
                count+=workMapping.insertWork(works.get(i));
                works.get(i).setWeek("2");
                count+=workMapping.insertWork(works.get(i));
                works.get(i).setWeek("3");
                count+=workMapping.insertWork(works.get(i));
                works.get(i).setWeek("4");
                count+=workMapping.insertWork(works.get(i));
                works.get(i).setWeek("5");
                count+=workMapping.insertWork(works.get(i));
            }
        }
        if(count>0){
            return true;
        }
        return false;
    }

    @Override
    public List<Work> getTableService(int userId) {
        List<Work> works = workMapping.selectAllWork();
        //不需要看见自己的id
        for (int i = 0; i < works.size(); i++) {
            if(works.get(i).getUserId()==userId&&!("-1".equals(works.get(i).getWeek()))){
                works.remove(i);
                i--;
            }
        }
        //储存工作表中用户id和工作work
        HashMap<Integer, List<Work>> idsWorks = new HashMap<>();
        //判断有哪些员工在工作列表中
        for (int i = 0; i < works.size(); i++) {
            if(idsWorks.containsKey(works.get(i).getUserId())){
                idsWorks.get(works.get(i).getUserId()).add(works.get(i));
            }else {
                idsWorks.put(works.get(i).getUserId(),new ArrayList<Work>());
            }

        }
        //储存请假通过的用户id和请假记录
        HashMap<Integer, List<Leave>> idsLeaveYes = new HashMap<>();
        List<Leave> leaves = leaveMapping.selectAllLeave();
        //获取通过状态为yes的请假记录
        for (int i = 0; i < leaves.size(); i++) {
            if("yes".equals(leaves.get(i).getAccess())){
                if(idsLeaveYes.containsKey(leaves.get(i).getUserId())){
                    idsLeaveYes.get(leaves.get(i).getUserId()).add(leaves.get(i));
                }else {
                    idsLeaveYes.put(leaves.get(i).getUserId(),new ArrayList<Leave>());
                }
            }
        }
        Set<Integer> set = idsWorks.keySet();
        int[] ids = new int[set.size()+1];
        int l=0;
        for (Integer in:set){
            ids[l++]=in;
        }
        //idsWorks是工作表中的员工id,works
        for (int i = 0; i < ids.length; i++) {
            //工作表中的所有员工中请假的员工
            if(idsLeaveYes.containsKey(ids[i])){
                //班次时间在请假时间的开始到结束之间，就移除
                for (int j=0;j<idsWorks.get(ids[i]).size();j++){
                    for (int k = 0; k < idsLeaveYes.get(ids[i]).size(); k++) {
                        if(isBetween(idsWorks.get(ids[i]).get(j),idsLeaveYes.get(ids[i]).get(k))){
                            works.remove(idsWorks.get(ids[i]).get(j));
                        }
                    }
                }
            }
        }

        return works;
    }

    /**
     * 班次时间在请假时间的开始到结束之间
     * @param work 工作时间 HH:mm:ss
     * @param leave 请假时间 yyyy-MM-dd HH:mm:ss
     * @return true表示work需要被移除
     */
    public  Boolean isBetween(Work work, Leave leave){
        //将work中的时间加上yyyy-mm-dd
        //获取当前日期
        Date currentTime = new Date();
        Calendar calendar=Calendar.getInstance();
        //获取当前星期
        Integer curWeek=calendar.get(Calendar.DAY_OF_WEEK)-1;
        //当前星期和传入工作时间星期差
        Integer sub = Integer.valueOf(work.getWeek())-curWeek;
        if(sub<0){
            sub+=7;
        }
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        String dateString = formatter.format(currentTime)+" "+work.getStartTime();
        String dateString2 = formatter.format(currentTime)+" "+work.getEndTime();


        DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date date = null;
        Date date2 = null;
        Date date3 = null;
        Date date4 = null;
        try {
            date = df.parse(dateString);
            date3 = df.parse(dateString2);
            date2 = df.parse(leave.getLeaveStartTime());
            date4 = df.parse(leave.getLeaveEndTime());
            //判断出来的week的开始时间搓
            long weekStartTime = date.getTime()+sub*24*60*60*1000;
            long weekEndTime = date3.getTime()+sub*24*60*60*1000;

            //请假开始时间搓
            long leaveStartTime = date2.getTime();
            long leaveEndTime = date4.getTime();
            if(weekStartTime>=leaveStartTime&&weekEndTime<=leaveEndTime){
                return true;
            }
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return false;
    }
    @Override
    public List<User> getWorkerListService(String startTime, String endTime, String week) {
        Work work = new Work();
        work.setStartTime(startTime);
        work.setWeek(week);
        work.setEndTime(endTime);
        List<Integer> integers = workMapping.selectUserIdByWork(work);
        List<User> users = new ArrayList<>();
        for (int i = 0; i < integers.size(); i++) {
            users.add(userMapping.selectUserByUserId(integers.get(i)));
        }
        return users;
    }

    @Override
    public boolean workerDeleteService(Work work) {
        int i=0;
        i= workMapping.deleteUserInWork(work);
        if(i>0)
            return true;
        return false;
    }

    @Override
    public List<User> getNoAddUserListService(List<Integer> userIds) {
        //查询所有员工
        List<User> users = userMapping.selectAllUser();
        for (int i = 0; i <userIds.size(); i++) {
            for (int j = 0; j < users.size(); j++) {
                if(userIds.get(i)==users.get(j).getUserId()){
                    users.remove(users.get(j));
                }
            }
        }
        return users;
    }

    @Override
    public boolean workerInsertService(Work work) {
        //判断是否已经存在，已经存在就不添加
        List<Work> works = workMapping.selectWorkByUserId(work.getUserId());
        for (int i = 0; i < works.size(); i++) {
            if(work.equals(works.get(i))){
                return false;
            }
        }
        int i=0;
        i = workMapping.insertWork(work);
        if (i>0)
            return true;
        return false;
    }

    @Override
    public List<Work> getUserTableService(int userId) {
//        查询所有week为-1的工作表
        List<Work> works = workMapping.selectAllWork();
        List<Work> works1 = new ArrayList<>();
        for (int i = 0; i < works.size(); i++) {
            if(works.get(i).getWeek().equals("-1")){
                works1.add(works.get(i));
            }
        }

        //查询员工的请假记录
        List<Leave> leaves = leaveMapping.selectLeaveByUserId(userId);
        works = workMapping.selectWorkByUserId(userId);
        for (int i = 0; i < works.size(); i++) {
            works1.add(works.get(i));
        }
        //删除不是yes的请假记录
        for (int i = 0; i < leaves.size(); i++) {
            if(!leaves.get(i).getAccess().equals("yes")){
                leaves.remove(leaves.get(i));
                i--;
            }
        }
        //判断工作表中是否存在已经请过假的，有就移除
        for (int i = 0; i < works1.size(); i++) {
            for (int j = 0; j < leaves.size(); j++) {
                if(works1.get(i).getUserId()==userId&&isBetween(works1.get(i),leaves.get(j))){
                    works1.remove(works1.get(i));
                    i--;
                    break;
                }
            }
        }
        return works1;
    }

    @Override
    public int modifyTimeTable(List<Work> works) {
        System.out.println("接收的"+works);
        //获取时刻表
        List<Work> works1 = utile.getTimeTable();
        System.out.println(works1);
        //将不同的时刻表单独拿出来
        List<Work> modifyWorks = new ArrayList<>();
        List<Work> preModifyWorks = works1;
        List<Work> conWorks = new ArrayList<>();
        int flag = 0;
        for (Work work:works) {
            flag=0;
            for (Work work1:works1) {
                if(work1.getStartTime().equals(work.getStartTime())&&work1.getEndTime().equals(work.getEndTime())){
                    flag=1;
                    conWorks.add(work1);
                    break;
                }
            }
            if(flag!=1){
                modifyWorks.add(work);
            }
        }

        for (Work work:conWorks) {
            preModifyWorks.remove(work);
        }

        //相当于查询出来的
        works1=conWorks;
        //需要加入的
        works=modifyWorks;
        System.out.println("需要修改的work"+preModifyWorks);
        System.out.println("修改后的"+works);
        System.out.println("不用修改的"+works1);
        for(int k=0;k<works1.size();k++){
            for(int l=0;l<works.size();l++){
                //若新的表的开始时间或者结束时间在之前的时刻表格中，就无法设置
                if(((works1.get(k).getStartTime().compareTo(works.get(l).getStartTime())<=0 && works1.get(k).getEndTime().compareTo(works.get(l).getStartTime())>=0)
                        || (works1.get(k).getStartTime().compareTo(works.get(l).getEndTime())<=0 && works1.get(k).getEndTime().compareTo(works.get(l).getEndTime())>=0))
                        ||  works1.get(k).getStartTime().compareTo(works.get(l).getStartTime())>=0 && works1.get(k).getEndTime().compareTo(works.get(l).getEndTime())<=0){
                    System.out.println(works);
                    preModifyWorks.remove(preModifyWorks.get(l));
                    works.remove(works.get(l));
                    l--;
                    System.out.println(works);
                }

            }

        }
        int count=0,i=0,j=0;
        for (i = 0; i < works.size(); i++) {
            count+=workMapping.updateWork(preModifyWorks.get(i),works.get(i));
        }
        return count;
    }

    @Override
    public int deleteTimeTable(Work work) {
        System.out.println(work);
        return workMapping.deleteTimeTable(work);
    }
}
